﻿using LF.Application.Aop;
using LF.Application.Services;
using LF.Application.Services.Iml;
using LF.Common;
using LF.Domain;
using LF.Domain.Services;
using LF.Domain.Services.Iml;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using SKIT.FlurlHttpClient.Wechat.TenpayV3.Utilities;
using System.IO;
using Volo.Abp.AutoMapper;
using Volo.Abp.BackgroundWorkers.Quartz;
using Volo.Abp.DynamicProxy;
using Volo.Abp.Json;
using Volo.Abp.Modularity;
using Serilog;
using Serilog.Events;
using Volo.Abp.Caching;

namespace LF.Application;

[DependsOn(typeof(AbpAutoMapperModule),typeof(DomainModule), typeof(AbpCachingModule), typeof(AbpBackgroundWorkersQuartzModule))]
public class LFModule:AbpModule
{
    public override void PreConfigureServices(ServiceConfigurationContext context)
    {
        context.Services.OnRegistered((action) => {
            bool should = !DynamicProxyIgnoreTypes.Contains(action.ImplementationType)
               && typeof(IApplicationService).IsAssignableFrom(action.ImplementationType);
            if (should)
            {
                action.Interceptors.TryAdd<AppUnitOfWorkInterceptor>();
            }
        });
        base.PreConfigureServices(context);
    }
    public override void ConfigureServices(ServiceConfigurationContext context)
    {
        var services = context.Services;
        var config = services.GetConfiguration();

        #region 提前注入，定时任务调用
        services.AddTransient<IParamConfigManagerService, ParamConfigManagerService>();
        services.AddTransient<IParamConfigService, ParamConfigService>();
        #endregion

        #region 微信小程序配置信息
        var weixin = config.GetSection("weixin");
        services.Configure<Weixin>(weixin);
        LFConfig.Weixin = weixin.Get<Weixin>()!;
        if (string.IsNullOrWhiteSpace(LFConfig.Weixin.Mode))
            LFConfig.Weixin.Mode = "release";
        var pay = config.GetSection("weixin").GetSection("pay");
        services.Configure<WeixinPay>(pay);
        LFConfig.WeixinPay = pay.Get<WeixinPay>()!;
        if (File.Exists(LFConfig.WeixinPay.PrivateKey.ToPath()))
        {
            LFConfig.WeixinPay!.PrivateKey = File.ReadAllText(LFConfig.WeixinPay.PrivateKey.ToPath());

        }
        if (File.Exists(LFConfig.WeixinPay.SerialNumber.ToPath()))
        {
            LFConfig.WeixinPay.SerialNumber = RSAUtility.ExportSerialNumberFromCertificate(File.ReadAllText(LFConfig.WeixinPay.SerialNumber.ToPath()));
        }
        #endregion
        #region 企业微信配置信息
        var qyweixin = config.GetSection("qyweixin");
        services.Configure<QyWeixin>(qyweixin);
        LFConfig.QyWeixin = qyweixin.Get<QyWeixin>();
        #endregion

        #region 发送短信配置信息
        var aliyun = config.GetSection("Aliyun");
        services.Configure<Aliyun>(aliyun);
        LFConfig.Aliyun = aliyun.Get<Aliyun>();
        #endregion

        #region 单项配置信息
        var limitDistance = config.GetValue<double>("limitDistance");
        LFConfig.LimitDistance = limitDistance;
        var iot = config.GetValue<string>("iot");
        LFConfig.Iot = iot!;
        var filehost = config.GetValue<string>("FileHost");
        LFConfig.FileHost = filehost!;
        var oaurl = config.GetValue<string>("OaUrl");
        LFConfig.OaUrl = oaurl!;
        var workWxApp = config.GetValue<string>("WorkWxApp");
        LFConfig.WorkWxApp = workWxApp!;
        var serviceurl = config.GetValue<string>("ServiceUrl");
        LFConfig.ServiceUrl = serviceurl!;
        var normalPwd = config.GetValue<string>("normalPwd");
        LFConfig.NormalPwd = normalPwd!;
        var tencentMapKey = config.GetValue<string>("TencentMapKey");
        LFConfig.TencentMapKey = tencentMapKey ?? "";
        var aMapKey = config.GetValue<string>("AMapKey");
        LFConfig.AMapKey = aMapKey ?? "";
        #endregion

        #region 目录配置
        var path = config.GetSection("file");
        services.Configure<FilePath>(path);
        LFConfig.FilePath = path.Get<FilePath>();
        if (LFConfig.FilePath!.Relative)
        {
            LFConfig.FilePath.Path = LFConfig.FilePath.Path.ToPath();
            LFConfig.FilePath.Temp = LFConfig.FilePath.Temp.ToPath();
        }
        #endregion

        #region 日志配置
        var logger = new LoggerConfiguration()
#if DEBUG
               .MinimumLevel.Debug()
               .WriteTo.Console(LogEventLevel.Information)
               .MinimumLevel.Override("Quartz", LogEventLevel.Warning)

#else
                .MinimumLevel.Information()
#endif
               .MinimumLevel.Override("Microsoft", LogEventLevel.Information)
               .MinimumLevel.Override("Volo.Abp",LogEventLevel.Warning)
               .WriteTo.File(new Serilog.Formatting.Json.JsonFormatter(), Path.Combine(LFConfig.FilePath.Path, "logs", "error", "error-.txt"), LogEventLevel.Error, rollingInterval: RollingInterval.Day)
               .WriteTo.File(new Serilog.Formatting.Json.JsonFormatter(), Path.Combine(LFConfig.FilePath.Path, "logs", "warn", "warn-.txt"), LogEventLevel.Warning, rollingInterval: RollingInterval.Day)
               .WriteTo.File(new Serilog.Formatting.Json.JsonFormatter(), Path.Combine(LFConfig.FilePath.Path, "logs", "info", "info-.txt"), LogEventLevel.Information, rollingInterval: RollingInterval.Day)
               .CreateLogger();

        Log.Logger = logger;
        services.AddSingleton<ILogger>(logger);
        DomainModuleEvents.LowerSqlAction = (sql) => Log.Logger.Warning($"慢SQL：{sql}");
        #endregion

        #region Aspose.cells注册
        new Aspose.Cells.License().SetLicense("Config/License.txt".ToPath());
        #endregion

        #region autoMapper配置
        services.AddAutoMapperObjectMapper<LFModule>();
        Configure<AbpAutoMapperOptions>(options =>
        {
            options.AddMaps<LFModule>(false);
            //options.AddProfile<LFProfile>(false);
        });
        #endregion
        //api 时间格式化
        Configure<AbpJsonOptions>(options => {
            options.OutputDateTimeFormat = "yyyy-MM-dd HH:mm:ss";
            options.InputDateTimeFormats = new List<string> { "yyyy-MM-dd HH:mm:ss" };
        });

        base.ConfigureServices(context);
    }
}
